package com.abel.bigwater.tlv.model

import io.netty.buffer.ByteBuf
import java.time.LocalDateTime
import kotlin.experimental.and

class TlvData6Period(
        var startClock: LocalDateTime? = null,
        var period: Short = 30,
        var count: Short = 0,
        var valueList: IntArray? = null) : TlvData(tag = PeriodDataParam.TAG) {

    override fun finalLen(): Int {
        length = 6 + 1 + 1 + 2 * count

        return length + 1 + 2
    }

    override fun fill(buf: ByteBuf): ByteBuf {
        if (length == 0) finalLen()

        with(buf.alloc().buffer()) {
            writeByte(tag.toInt())
            writeShort(length)

            writeBytes(TlvHelper.toByteArray(startClock ?: LocalDateTime.now()))
            writeByte(period.toInt())
            writeByte(count.toInt())

            if (valueList?.size != count.toInt())
                throw TlvInvalidException("value should be same as count: ${valueList?.size} != ${count}")

            valueList!!.forEach { writeShort(it) }

            buf.writeBytes(this)
        }

        return buf
    }

    /**
     * buf is consumed dedicatedly
     */
    override fun parse(buf: ByteBuf): ByteBuf {
        val tag2 = buf.readByte().toShort() and 0xFF
        val length2 = buf.readShort().toInt() and 0xFFFF
        if (buf.readableBytes() < length2) throw TlvInvalidException("invalid bytes: ${buf.readableBytes()} < ${length2}")

        startClock = TlvHelper.toLocalDateTime(let {
            val ba = ByteArray(6)
            buf.readBytes(ba)
            ba
        })

        period = buf.readByte().toShort() and 0xFF
        count = buf.readByte().toShort() and 0xFF

        valueList = IntArray(count.toInt())
        for (idx in 0..count - 1) {
            valueList!![idx] = buf.readShort().toInt() and 0xFFFF
        }

        return buf
    }
}